/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.hadss.avoidareasample;

import android.content.Context;

import com.facebook.flipper.android.AndroidFlipperClient;
import com.facebook.flipper.android.utils.FlipperUtils;
import com.facebook.flipper.core.FlipperClient;
import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin;
import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin;
import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin;
import com.facebook.flipper.plugins.inspector.DescriptorMapping;
import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
import com.facebook.react.ReactInstanceEventListener;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.modules.network.NetworkingModule;

import okhttp3.OkHttpClient;

/**
 * @description Class responsible of loading Flipper inside your React Native application. This is the debug
 * flavor of it. Here you can add your own plugins and customize the Flipper setup.
 * @since 2025/5/29
 */
public class ReactNativeFlipper {
    /**
     * 初始化Flipper
     *
     * @param context              context
     * @param reactInstanceManager reactInstanceManager
     */
    public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
        if (FlipperUtils.shouldEnableFlipper(context)) {
            dealInitializeFlipper(context, reactInstanceManager);
        }
    }

    /**
     * 处理Flipper的初始化
     *
     * @param context              context
     * @param reactInstanceManager reactInstanceManager
     */
    private static void dealInitializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
        final FlipperClient client = AndroidFlipperClient.getInstance(context);

        client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
        client.addPlugin(new DatabasesFlipperPlugin(context));
        client.addPlugin(new SharedPreferencesFlipperPlugin(context));
        client.addPlugin(CrashReporterPlugin.getInstance());

        NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
        NetworkingModule.setCustomClientBuilder(
            new NetworkingModule.CustomClientBuilder() {
                @Override
                public void apply(OkHttpClient.Builder builder) {
                    builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
                }
            });
        client.addPlugin(networkFlipperPlugin);
        client.start();

        // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
        // Hence we run if after all native modules have been initialized
        ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
        if (reactContext == null) {
            addPlugin(reactInstanceManager, client);
        } else {
            client.addPlugin(new FrescoFlipperPlugin());
        }
    }

    /**
     * 添加插件
     *
     * @param reactInstanceManager reactInstanceManager
     * @param client               client
     */
    private static void addPlugin(ReactInstanceManager reactInstanceManager, FlipperClient client) {
        reactInstanceManager.addReactInstanceEventListener(
            new ReactInstanceEventListener() {
                @Override
                public void onReactContextInitialized(ReactContext reactContext) {
                    reactInstanceManager.removeReactInstanceEventListener(this);
                    dealAddPlugin(reactContext, client);
                }


            });
    }

    /**
     * 处理添加插件
     *
     * @param reactContext reactContext
     * @param client       client
     */
    private static void dealAddPlugin(ReactContext reactContext, FlipperClient client) {
        reactContext.runOnNativeModulesQueueThread(
            new Runnable() {
                @Override
                public void run() {
                    client.addPlugin(new FrescoFlipperPlugin());
                }
            });
    }
}
